package com.xhwl.centiotdata.suppliersystem.haikang;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.phonogram.PhonogramIntegrationFactory;
import com.xhwl.centiotdata.handler.phonogram.PhonogramIntegrationHandler;
import com.xhwl.centiotdata.mq.producer.GeneralProducer;
import com.xhwl.centiotdata.pojo.constant.HaiKangConstant;
import com.xhwl.centiotdata.pojo.dto.brodcast.BroadCastData;
import com.xhwl.centiotdata.pojo.dto.brodcast.PhonogramConfigDTO;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.utils.HttpUtils;
import com.xhwl.common.constant.cent.alarm.AlarmConstant;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.iotdata.haikang.BroadcastDTO;
import com.xhwl.common.enums.ProductEnum;
import com.xhwl.common.enums.device.DeviceOnlineStatusEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.alarm.AlarmManagement;
import com.xhwl.common.pojo.cent.device.Device;
import com.xhwl.common.query.cent.device.DeviceQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 音柱处理
 *
 * @author pengjunming
 * @description
 * @date 2022/10/8 9:39
 */
@Service
@Slf4j
public class PhonogramHaiKangHandler extends PhonogramIntegrationHandler {

    @Resource
    private GeneralHaiKangHandler generalHaiKangHandler;

    @Autowired
    private IDeviceCentService deviceCentService;

    @Autowired
    GeneralProducer generalProducer;

    @Override
    public ResultJson customBroadCast(PhonogramConfigDTO config, BroadcastDTO dto, DeviceDTO deviceDTO) {
        try {
            //通过音柱设备的第三方标识，获取该音柱的广播点信息
            Map<String, Object> params = new HashMap<>();
            params.put("pageNo", 1);
            params.put("pageSize", 10);
            params.put("deviceIndexCode", deviceDTO.getThirdDeviceId());
            String broadResult = HttpUtils.postHaiKangZhiHuiHttpsUrl(config.getIpAndPort(),
                    config.getAk(), config.getSk(), HaiKangConstant.PULL_BROAD_BY_DEVICE,
                    JSONObject.toJSONString(params), "https");
            if(!this.haiKangResponseHandler(broadResult)){
                log.error("调用海康获取广播点接口失败");
                return ResultJson.fail("调用海康获取广播点接口失败");
            }
            JSONArray broadArray = JSONObject.parseArray(JSONObject.parseObject(
                    JSONObject.parseObject(broadResult).getString("data")).getString("list"));
            JSONObject broadObject = JSONObject.parseObject(broadArray.get(0).toString());

            BroadCastData data = new BroadCastData();
            data.setPriority(Objects.isNull(dto.getPriority()) ? 1 : dto.getPriority());
            data.setState(Objects.isNull(dto.getState()) ? 1 : dto.getState());
            data.setPlayTtsContent(dto.getMessageContent());
            data.setBroadCastMode("tts");
            data.setAudioPointIndexCode(Collections.singletonList(broadObject.getString("audioChannelIndexCode")));

            //由于音柱厂商虽然是海康，但是鉴权方式一个海康ISC，一个是海康智慧广播
            String result = HttpUtils.postHaiKangZhiHuiHttpsUrl(config.getIpAndPort(),
                    config.getAk(), config.getSk(), HaiKangConstant.CUSTOM_BROADCAST,
                    JSONObject.toJSONString(data), "https");

            if(!this.haiKangResponseHandler(result)){
                log.error("调用海康控制音柱接口失败");
                return ResultJson.fail("调用海康控制音柱接口失败");
            }

            return ResultJson.success();
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultJson.fail(e.getMessage());
        }
    }

    @Override
    public void pullYinZhuDevice(PhonogramConfigDTO config) {
        JSONArray yinZhuDeviceArray = new JSONArray();
        JSONArray yinZhuDeviceList = null;
        JSONArray broadDeviceArray = new JSONArray();
        Integer pageNo = 1;
        //分页获取海康-智慧广播的音柱设备信息
        do {
            Map<String, Object> params = new HashMap<>();
            params.put("pageNo", pageNo);
            params.put("pageSize", 1000);

            String result = HttpUtils.postHaiKangZhiHuiHttpsUrl(config.getIpAndPort(),
                    config.getAk(), config.getSk(), HaiKangConstant.PULL_YINZHU_DEVICE,
                    JSONObject.toJSONString(params), "https");
            if(!this.haiKangResponseHandler(result)){
                log.error("调用海康音柱接口失败");
                throw new BusinessException("调用海康音柱接口失败");
            }

            yinZhuDeviceList = JSONObject.parseArray(JSONObject.parseObject(
                    JSONObject.parseObject(result).getString("data")).getString("list"));

            yinZhuDeviceArray.addAll(yinZhuDeviceList);
            pageNo++;

        }while (!CollectionUtils.isEmpty(yinZhuDeviceList) && yinZhuDeviceList.size() == 1000);
        log.info("拉取海康-智慧广播的音柱设备，设备类型为{}，信息为：{}", config.getDeviceType(), JSONObject.toJSONString(yinZhuDeviceArray));
        //分页查询海康-智慧广播的音柱广播点信息
        Map<String, Object> params = new HashMap<>();
        params.put("pageNo", 1);
        params.put("pageSize", 1000);
        String result = HttpUtils.postHaiKangZhiHuiHttpsUrl(config.getIpAndPort(),
                config.getAk(), config.getSk(), HaiKangConstant.PULL_BROAD_PAGE,
                JSONObject.toJSONString(params), "https");
        if(!this.haiKangResponseHandler(result)){
            log.error("调用海康获取广播点接口失败");
            throw new BusinessException("调用海康获取广播点接口失败");
        }
        broadDeviceArray = JSONObject.parseArray(JSONObject.parseObject(
                JSONObject.parseObject(result).getString("data")).getString("list"));
        //处理海康-智慧广播返回的设备信息，并将其封装为中台的设备实体类
        List<DeviceDTO> deviceDTOS = this.handleDeviceData(config, yinZhuDeviceArray, broadDeviceArray);
        //根据设备的状态来判断是否告警
        this.alarmBroadDevice(deviceDTOS);
        //将设备信息存储到设备模块
        deviceCentService.asyncUpdateDevice(deviceDTOS);
    }

    /**
     * 处理海康音柱的返回值
     */
    private Boolean haiKangResponseHandler(String result){
        JSONObject jsonObject = JSONObject.parseObject(result);
        if(jsonObject.isEmpty()){
            return false;
        }
        if(!"0".equals(jsonObject.getString("code"))){
            log.info("调用海康音柱失败消息为：{}", jsonObject.getString("msg"));
            return false;
        }
        return true;
    }

    /**
     * 将海康音柱返回的信息整理为中台设备对象
     */
    private List<DeviceDTO> handleDeviceData(PhonogramConfigDTO config, JSONArray deviceArray, JSONArray broadArray){
        return deviceArray.stream().map(object -> {
            JSONObject deviceObject = JSONObject.parseObject(object.toString());
            DeviceDTO deviceDTO = new DeviceDTO();
            deviceDTO.setProjectId(config.getProjectId());
            deviceDTO.setProductId(config.getProductId());
            deviceDTO.setCategoryId(config.getCategoryId());
            deviceDTO.setDeviceTypeId(config.getDeviceType());
            deviceDTO.setName(deviceObject.getString("deviceName"));
            deviceDTO.setThirdDeviceId(deviceObject.getString("deviceIndexCode"));
            deviceDTO.setOnlineStatus(DeviceOnlineStatusEnum.OFFLINE.getId());
            for (Object o : broadArray) {
                JSONObject broadObject = JSONObject.parseObject(o.toString());
                if(StringUtils.equals(broadObject.getString("parentDevIndexCode"), deviceObject.getString("deviceIndexCode"))){
                    deviceDTO.setOnlineStatus(this.broadStatusToCent(broadObject.getInteger("state")));
                }
            }
            return deviceDTO;
        }).collect(Collectors.toList());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        PhonogramIntegrationFactory.register(ProductEnum.HAIKANG_ISC.getId(), this);
    }

    /**
     * 对设备离线的设备进行告警推送
     */
    private void alarmBroadDevice(List<DeviceDTO> deviceDTOS){
        List<DeviceDTO> offDeviceDTOList = deviceDTOS.stream().filter(deviceDTO -> deviceDTO.getOnlineStatus() == DeviceOnlineStatusEnum.OFFLINE.getId()).collect(Collectors.toList());
        if(!offDeviceDTOList.isEmpty()){
            DeviceQuery deviceQuery = new DeviceQuery();
            deviceQuery.setProjectId(offDeviceDTOList.get(0).getProjectId());
            deviceQuery.setThirdDeviceIdList(offDeviceDTOList.stream().map(DeviceDTO::getThirdDeviceId).collect(Collectors.toList()));
            List<DeviceDTO> deviceDTOList = deviceCentService.listDevice(null, deviceQuery);
            for (DeviceDTO deviceDTO : deviceDTOList) {
                AlarmManagement alarmManagement = new AlarmManagement();
                alarmManagement.setProjectId(deviceDTO.getProjectId());
                alarmManagement.setAlarmTime(new Date());
                alarmManagement.setDeviceId(deviceDTO.getId());
                alarmManagement.setAlarmInventoryCode("99176537");
                generalProducer.send(AlarmConstant.ALARM_TOPIC, alarmManagement);
            }
        }
    }

    /**
     * 将广播点的在线状态转为中台设备的在线状态
     */
    private Integer broadStatusToCent(Integer broadStatus){
        switch (broadStatus){
            case 0:
                return DeviceOnlineStatusEnum.ONLINE.getId();
            default:
                return DeviceOnlineStatusEnum.OFFLINE.getId();
        }
    }
}
